#ifndef MODIFIED_APPROACH_H
#define MODIFIED_APPROACH_H

#include <thrust/device_vector.h>
#include <thrust/transform_reduce.h>
#include <thrust/functional.h>
#include <vector>
#include <string>
using namespace std;
using namespace thrust;

#define MAX_DIM_X 128 // max first dimension size of keyword
#define MAX_DIM_Y 256 // max second dimension size of keyword

#define THREAD_PER_BLK 128

struct Result{
	int query;
	int feature_id;
	float count;
	int lb;
	int ub;
};

// compare upper bound of Result object
struct Ubcomapre
{
	__host__ __device__ bool operator()(const Result &lhs, const Result &rhs) const{
		if(lhs.query < rhs.query) return true;
		else if(lhs.query > rhs.query) return false;
		if(lhs.ub == rhs.ub) return lhs.lb < rhs.lb;
		else return lhs.ub < rhs.ub;
		//return lhs.query < rhs.query || (lhs.query == rhs.query && lhs.ub < rhs.ub);
	}
};

// compare lower bound of Result object
struct Lbcompare
{
	__host__ __device__ bool operator()(const Result &lhs, const Result &rhs) const{
		if(lhs.query < rhs.query) return true;
		else if(lhs.query > rhs.query) return false;
		return lhs.lb < rhs.lb;

		//return lhs.query < rhs.query || (lhs.query == rhs.query && lhs.lb < rhs.lb);
	}
};

// initilize problem including setting gpu memory 
// if want to random generate, put in empty string
void init_problem(string inv_list_dir,string query_file_path,int num_of_query);

// compute of the counting
bool compute_feature_mapping(vector<Result>& result,int N,int lb,int ub,float threshold, int K);

// clear gpu memory
void clear_gpu();


#endif